﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using FlexCel.Core;
using Newtonsoft.Json.Linq;
using PEC.Util;

namespace PEC
{
    public partial class FrmTerminator : Form
    {
        bool _reset = false;
        private int delayCell = 8;
        int packageLen = 1024;
        int portNumber = 9050;
        UdpClient receiver;
        PecController _pecController;

        List<MySerialPort> ports = new List<MySerialPort>();
        string InputData = string.Empty, _frame = "", STX = Convert.ToChar(2).ToString(), EOT = Convert.ToChar(4).ToString();
        string _parternRTU = @"^" + Convert.ToChar(2).ToString() + @".{1}C[0-9]{4}" + Convert.ToChar(4).ToString() + @"$",//
            _parternLight = @"^" + Convert.ToChar(2).ToString() + @".{1}C[0-9]{4}" + Convert.ToChar(4).ToString() + @"$",
            _parternKANBAN = @"^" + Convert.ToChar(2).ToString() + @"0[0-9]{2}[0-9]{4}..." + Convert.ToChar(4).ToString() + @"$";

        List<List<CachedRTU>> CachedRTUs = new List<List<CachedRTU>>();
        List<string[]> CachedDataSends = new List<string[]>();
        List<CachedLCD> CachedLCDs = new List<CachedLCD>();
        List<DTO.OpGioInfo> CachedTimes = new List<DTO.OpGioInfo>();
        List<DTO.ChuyenSanXuatInfo> CachecLines = new List<DTO.ChuyenSanXuatInfo>();
        delegate void DbUpdateTatkTimeCallback(int com, int rtu);
        delegate void DbUpdateSanLuongCallback(int line);
        delegate void Send2LCDCallback(CachedRTU rtu);
        public FrmTerminator(PecController pec)
        {
            _pecController = pec;
            InitializeComponent();
        }

        private void FrmTerminator_Load(object sender, EventArgs e)
        {
            Initialze();
        }

        private void Initialze()
        {
            InitializeTime();
            InitializeBDT();
            InitializeCOM();
            InitializeRTU();
            InitializeLCD();
            LoadCOMCached();
        }

        private void InitializeRTU()
        {
            string sErr = null;
            BUS.OpRtuControl ctr = new BUS.OpRtuControl(_pecController.Bus);
            BUS.OpLenhSXControl lsxCtr = new BUS.OpLenhSXControl(ctr);
            DTO.OpRtuInfo[] rtus = ctr.GetByFilter(_pecController.XuongId, null, ref sErr);

            if (!string.IsNullOrEmpty(sErr)) Log(sErr);
            else
            {
                foreach (var x in rtus)
                {
                    if (CachedRTUs.Count < x.ComId)
                    {
                        while (CachedRTUs.Count < x.ComId)
                        {
                            CachedRTUs.Add(null);
                        }
                    }
                    if (CachedRTUs[x.ComId.Value - 1] == null) CachedRTUs[x.ComId.Value - 1] = new List<CachedRTU>();
                    if (CachedRTUs[x.ComId.Value - 1].Count <= x.RtuID)
                    {
                        while (CachedRTUs[x.ComId.Value - 1].Count <= x.RtuID)
                        {
                            CachedRTUs[x.ComId.Value - 1].Add(null);
                        }
                    }
                    CachedRTUs[x.ComId.Value - 1][x.RtuID.Value] = new CachedRTU()
                    {
                        com = x.ComId.Value,
                        idRtu = x.RtuID.Value,
                        dv = x.DonVi.Value,
                        lenhSX = x.LenhSX,
                        line = x.LineId.Value
                    };
                    DTO.FilterParameterCollection filters = new DTO.FilterParameterCollection();
                    filters.Add("LenhSX", x.LenhSX);
                    DTO.OpLenhSXInfo[] infs = lsxCtr.GetByFilter(filters, ref sErr);
                    if (infs != null && infs.Length > 0)
                    {
                        CachedRTUs[x.ComId.Value - 1][x.RtuID.Value].reCalculate = infs[0].Status == "ReCalculate";
                    }
                }
                //     rtus ->       CachedRTUs
            }
        }

        private void InitializeLCD()
        {
            receiver = new UdpClient(portNumber);
            receiver.BeginReceive(new AsyncCallback(ReceivedData), receiver);
        }
        private void InitLCDCached(string ip, string s)
        {
            //{ i:0, id: 1 }
            try
            {
                JObject jo = JObject.Parse(s);
                if (string.Format("{0}", jo["i"]) == "0")
                {
                    if (jo["id"] != null)
                    {
                        int line = int.Parse(jo["id"].ToString());
                        if (line > 0)
                        {
                            string oIP = lcdFindIP(line);
                            if (!string.IsNullOrEmpty(oIP))
                            {
                                lcdUpdateIP(line, ip);
                            }
                            else
                            {
                                lcdAddLine(line, ip);
                            }
                            OnLCDReceiver(line, s);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
            }
            finally
            {
            }
        }
        private void lcdAddLine(int line, string ip)
        {
            CachedLCDs.Add(new CachedLCD()
            {
                line = line,
                ip = ip
            });
        }
        private void lcdUpdateIP(int line, string ip)
        {
            foreach (var x in CachedLCDs)
            {
                if (x.line == line)
                {
                    x.ip = ip;
                    break;
                }
            }
        }
        private void ReceivedData(IAsyncResult iar)
        {
            IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0);
            UdpClient receiver = (UdpClient)iar.AsyncState;
            try
            {
                byte[] data = receiver.EndReceive(iar, ref iep);
                string s = Encoding.UTF8.GetString(data).Trim();
                int line = lcdFindLine(iep.ToString());
                if (line > 0)
                {
                    OnLCDReceiver(line, s);
                }
                else
                {
                    InitLCDCached(iep.ToString(), s);
                }
                if (!s.ToUpper().Equals("QUIT")) receiver.BeginReceive(new AsyncCallback(ReceivedData), receiver);
            }
            catch (Exception ex)
            {
                Log(string.Format("Socket is Closed{1}", ex.Message, Environment.NewLine));
            }
        }
        private int lcdFindLine(string ip)
        {
            int line = -1;
            foreach (var x in CachedLCDs)
            {
                if (x.ip == ip)
                {
                    line = x.line;
                    break;
                }
            }
            return line;
        }
        private void OnLCDReceiver(int line, string s)
        {
            // Setup: {tt:000,mt1:000,mt2:00,xs:["NV001",null,null,null,null,null],gy:"dsdsdsdsds",i:1}
            try
            {
                JObject jo = JObject.Parse(s);
                if (!string.IsNullOrEmpty(string.Format("{0}", jo["i"])))
                {
                    if (CachecLines.Count > line && CachecLines[line - 1] != null)
                    {
                        var x = CachecLines[line - 1];
                        bool reCal = false;
                        if (jo["tt"] != null)
                        {
                            reCal = true;
                            x.HoanTat1 = Convert.ToInt32(jo["tt"]);
                        }
                        if (jo["mt1"] != null)
                        {
                            reCal = true;
                            x.DinhMuc1 = Convert.ToInt32(jo["mt1"]);
                        }
                        if (jo["mt2"] != null) x.DinhMuc2 = Convert.ToInt32(jo["mt2"]);
                        if (jo["gy"] != null) x.Comments = Convert.ToString(jo["gy"]);
                        if (x.Lcds != null && x.Lcds.Length > 0)
                        {
                            if (jo["xs"] is JArray)
                            {
                                var xss = (JArray)jo["xs"];

                                for (var i = 0; i < xss.Count; i++)
                                {
                                    if (i == 0) x.Lcds[0].CongNhan1 = xss[i].ToString();
                                    else if (i == 1) x.Lcds[0].CongNhan2 = xss[i].ToString();
                                    else if (i == 2) x.Lcds[0].CongNhan3 = xss[i].ToString();
                                    else if (i == 3) x.Lcds[0].CongNhan4 = xss[i].ToString();
                                    else if (i == 4) x.Lcds[0].CongNhan5 = xss[i].ToString();
                                    else if (i == 5) x.Lcds[0].CongNhan6 = xss[i].ToString();
                                    else if (i == 6) x.Lcds[0].CongNhan7 = xss[i].ToString();
                                }
                            }
                        }

                        if (reCal)
                        {
                            Calculator(line, 0, reCal);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
            }
            finally
            {
            }
        }

        private Image LoadImage(string p)
        {
            string noImage = Application.StartupPath + "Imgs\\noimage.png";
            string path = string.Format("{0}{1}{2}.png", Application.StartupPath, "Imgs\\", p);
            if (File.Exists(path))
            {
                return Image.FromFile(path);
            }
            return Image.FromFile(noImage);
        }

        private void SendLCD(int line, string val)
        {
            if (val == null) return;
            string ip = null;
            ip = lcdFindIP(line);
            if (string.IsNullOrEmpty(ip))
            {
                IPEndPoint iepRemote = new IPEndPoint(IPAddress.Parse(ip), portNumber);
                UdpClient send = new UdpClient();

                byte[] data = new byte[packageLen];
                data = Encoding.UTF8.GetBytes(val);
                send.BeginSend(data, data.Length, iepRemote, new AsyncCallback(EndSend), send);
            }
        }

        private void EndSend(IAsyncResult iar)
        {
            UdpClient send = (UdpClient)iar.AsyncState;
            send.Close();
        }

        private string lcdFindIP(int line)
        {
            string ip = null;
            foreach (var x in CachedLCDs)
            {
                if (x.line == line)
                {
                    ip = x.ip;
                    break;
                }
            }
            return ip;
        }

        private void LoadCOMCached()
        {
            string[] comPorts = _pecController.ComPorts.Split('|');
            for (int i = 1; i <= 6; i++)
            {
                if (comPorts.Length >= i)
                {
                    if (gpCOM.Controls["ckPort" + i].Visible && gpCOM.Controls["ckPort" + i].Text == comPorts[i - 1])
                    {
                        ((CheckBox)gpCOM.Controls["ckPort" + i]).Checked = true;
                    }
                }
            }
        }

        private void InitializeCOM()
        {
            string[] portNames = SerialPort.GetPortNames();
            if (portNames.Length == 0) portNames = new string[] { "COM DEMO" };
            for (int i = 1; i <= 6; i++)
            {
                if (portNames.Length >= i)
                {
                    gpCOM.Controls["ckPort" + i].Text = portNames[i - 1];
                }
                else
                {
                    gpCOM.Controls["ckPort" + i].Visible = false;
                }
            }
        }

        private void InitializeBDT()
        {
            string sErr = null;
            BUS.ChuyenSanXuatControl ctr = new BUS.ChuyenSanXuatControl(_pecController.Bus);
            DTO.ChuyenSanXuatInfo[] chuyens = ctr.GetByFilter(_pecController.XuongId, null, ref sErr);


            if (!string.IsNullOrEmpty(sErr)) Log(sErr);
            else
            {
                foreach (var x in chuyens)
                {
                    if (CachecLines.Count < x.LineId)
                    {
                        while (CachecLines.Count < x.LineId)
                        {
                            CachecLines.Add(null);
                        }
                    }
                    CachecLines[x.LineId.Value - 1] = x;
                    int todayTimes = 0;
                    for (int i = 1; i <= 20; i++)
                    {
                        todayTimes += Convert.ToInt32(CachedTimes[x.LineId.Value - 1].GetValue("GioLam" + i));
                    }
                    x.WorkTimeOfDay = todayTimes;
                }
            }
        }
        private void InitializeTime()
        {
            string sErr = null;
            BUS.OpGioControl ctr = new BUS.OpGioControl(_pecController.Bus);
            DTO.OpGioInfo[] chuyens = ctr.GetByFilter(_pecController.XuongId, null, ref sErr);

            if (!string.IsNullOrEmpty(sErr)) Log(sErr);
            else
            {
                foreach (var x in chuyens)
                {
                    if (CachedTimes.Count < x.LineId)
                    {
                        while (CachedTimes.Count < x.LineId)
                        {
                            CachedTimes.Add(null);
                        }
                    }
                    CachedTimes[x.LineId.Value - 1] = x;
                }
            }
        }

        private void btClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btCloseAndReset_Click(object sender, EventArgs e)
        {
            _reset = true;
            Close();
        }

        private void FrmTerminator_FormClosed(object sender, FormClosedEventArgs e)
        {

        }

        private void FrmTerminator_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_reset)
            {
                ConfigTools.Change("ComPorts", "");
            }
            else
            {
                string ports = "";
                for (int i = 1; i <= 6; i++)
                {
                    if (gpCOM.Controls["ckPort" + i].Visible && ((CheckBox)gpCOM.Controls["ckPort" + i]).Checked)
                    {
                        ports += gpCOM.Controls["ckPort" + i].Text + "|";
                    }

                }
                ConfigTools.Change("ComPorts", ports);
            }
        }

        private void Com_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox cb = sender as CheckBox;

            EnableCom(cb.Text, cb.Checked);
        }

        private void EnableCom(string comName, bool enable)
        {
            bool flag = false;
            foreach (MySerialPort p in ports)
            {
                if (p.PortName == comName)
                {
                    flag = true;
                    if (enable)
                    {
                        if (!p.Port.IsOpen) p.Port.Open();

                    }
                    else
                    {
                        if (p.Port.IsOpen) p.Port.Close();
                    }
                }
            }

            if (!flag)
            {
                MySerialPort p = new MySerialPort() { PortName = comName };
                p.Port = new SerialPort(comName);
                ports.Add(p);
                p.Port.DataReceived += Port_DataReceived;
                p.Port.Open();

            }
        }

        void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sport = sender as SerialPort;
            byte[] bs = new byte[8];
            sport.Read(bs, 0, 8);

            string partern = STX + ".{6}" + EOT;
            _frame += Encoding.ASCII.GetString(bs).Trim();
            //_frame += ((char)bs[0]).ToString() +
            //    ((char)bs[1]).ToString() +
            //    ((char)bs[2]).ToString() +
            //    ((char)bs[3]).ToString() +
            //    ((char)bs[4]).ToString() +
            //    ((char)bs[5]).ToString() +
            //    ((char)bs[6]).ToString() +
            //    ((char)bs[7]).ToString();
            if (_frame != "")
            {
                if (_frame.IndexOf(STX) > 0)
                    _frame = _frame.Substring(_frame.IndexOf(STX));
                //partern = "(?=" + STX + ")" + "[^" + EOT + "]" + EOT;
                MatchCollection arrMatch = Regex.Matches(_frame, partern);
                foreach (Match match in arrMatch)
                {
                    string value = match.Value;

                    if (Regex.IsMatch(value, _parternRTU))
                    {
                        MyDataPackage pac = new MyDataPackage()
                        {
                            com = GetPortIndex(sport.PortName),
                            portName = sport.PortName,
                            type = "F",
                            id = value[1],
                            data = value.Substring(value.Length - 4, 4)
                        };

                        ReceivedPackage(pac);
                    }
                    _frame = _frame.Replace(value, "");
                }
            }

        }

        private int GetPortIndex(string portName)
        {
            for (int i = 1; i <= 6; i++)
            {
                if (gpCOM.Controls["ckPort" + i].Text == portName) return i - 1;
            }
            return -1;
        }

        private void ReceivedPackage(MyDataPackage pac)
        {
            if (pac.type == "F")
            {
                if (CachedRTUs.Count > pac.com && CachedRTUs[pac.com - 1].Count > pac.id)
                {
                    CachedRTU rtu = CachedRTUs[pac.com][pac.id];
                    if (rtu != null)
                    {
                        int count = Convert.ToInt32(pac.data) * rtu.dv;
                        Calculator(rtu, count);
                    }
                }
            }
        }

        private void Calculator(CachedRTU rtu, int count)
        {
            CalcTatkTime(rtu, count);
            CalcSanLuong(rtu, count);
        }
        private void Calculator(int line, int count, bool reCal)
        {
            CachedRTU rtu = new CachedRTU()
            {
                line = line,
                reCalculate = reCal
            };
            //  CalcTatkTime(rtu, count);
            CalcSanLuong(rtu, count);
        }
        DataTable gtt = new DataTable();
        private void CalcSanLuong(CachedRTU rtu, int count)
        {
            int mins = Convert.ToInt32((DateTime.Now - DateTime.Today).TotalMinutes);
            int now = mins - CachedTimes[rtu.line - 1].BatDau.Value;
            int totalGL = 0;
            int totalGN = 0;
            if (gtt.Rows.Count == 0) gtt.Rows.Add(gtt.NewRow());
            for (int i = 1; i <= 20; i++)
            {
                if (!gtt.Columns.Contains("GioTT" + i))
                {
                    gtt.Columns.Add("GioTT" + i);
                    gtt.Rows[0]["GioTT" + i] = 0;
                }
            }
            for (int i = 1; i <= 20; i++)
            {
                int gl = Convert.ToInt32(CachedTimes[rtu.line - 1].GetValue("GioLam" + i));
                int gn = Convert.ToInt32(CachedTimes[rtu.line - 1].GetValue("GioNghi" + i));

                if (now <= totalGL + totalGN + gl + gn)
                {
                    int tmp = now - (totalGL + totalGN);
                    CachecLines[rtu.line - 1].WorkTimeOfNow = totalGL + Math.Min(tmp, gl);
                    break;
                }
                else
                {
                    int tmp = now - (totalGL + totalGN);
                    gtt.Rows[0]["GioTT" + i] = Math.Min(tmp, gl);
                }
                totalGL += gl;
                totalGN += gn;
            }

            if (rtu.reCalculate == true)
            {
                BUS.OpGioControl ctr = new BUS.OpGioControl(_pecController.Bus);
                int idx = ctr.GetTimePos(CachedTimes[rtu.line - 1], DateTime.Now);
                if (idx == 0) return;
                if (CachecLines[rtu.line - 1].Lcds != null && CachecLines[rtu.line - 1].Lcds.Length > 0)
                {
                    CachecLines[rtu.line - 1].Lcds[0].AddValue("SanLuong" + idx, count);
                    // CachecLines[rtu.line - 1].Lcds[0].SetSanLuong(idx, count);
                }
                CachecLines[rtu.line - 1] = CalcExcel(CachecLines[rtu.line - 1], count);
            }
            else
            {
                CachecLines[rtu.line - 1].AddValue(rtu.lenhSX, count);
            }

            int newVal = GetNewRTUValue(rtu);
            Return2RTU(rtu, newVal);
            Send2LCDCallback sendCB = new Send2LCDCallback(Send2LCD);
            sendCB.BeginInvoke(rtu, null, null);
            DbUpdateSanLuongCallback dbSanLuong = new DbUpdateSanLuongCallback(DbUpdateSanLuong);
            dbSanLuong.BeginInvoke(rtu.line, null, null);
        }


        private DTO.ChuyenSanXuatInfo CalcExcel(DTO.ChuyenSanXuatInfo chuyenSanXuatInfo, int count)
        {
            string tempPath = Application.StartupPath + "Report";
            string rptPath = Application.StartupPath + "tmp";
            if (!File.Exists(tempPath + "\\CalcExcel.template.xls")) return chuyenSanXuatInfo;
            DataSet ds = new DataSet();
            DataTable dt = chuyenSanXuatInfo.ToDataTable();
            dt.Rows.Add(chuyenSanXuatInfo.ToDataRow(dt));
            dt.TableName = "chuyen";
            ds.Tables.Add(dt);
            if (chuyenSanXuatInfo.Lcds != null && chuyenSanXuatInfo.Lcds.Length > 0)
            {
                DataTable dtLCD = chuyenSanXuatInfo.Lcds[0].ToDataTable();
                dtLCD.Rows.Add(chuyenSanXuatInfo.Lcds[0].ToDataRow(dtLCD));
                dtLCD.TableName = "lcd";
                ds.Tables.Add(dtLCD);
            }

            ReportGenerator rg = new ReportGenerator(ds, "CalcExcel", chuyenSanXuatInfo.XuongId, "", tempPath, rptPath);
            ExcelFile xls = rg.CreateReport();
            DataTable dtNChuyen = new DataTable("chuyen");
            DataTable dtNLCD = new DataTable("lcd");
            int total = 0;
            TransferHelper.PreviewExcelFile(dt, xls, "", "chuyen", ref total);
            TransferHelper.PreviewExcelFile(dtNLCD, xls, "", "lcd", ref total);
            if (dtNChuyen.Rows.Count == 1) chuyenSanXuatInfo = new DTO.ChuyenSanXuatInfo(dtNChuyen.Rows[0]);
            if (dtNLCD.Rows.Count == 1)
            {
                chuyenSanXuatInfo.Lcds = new DTO.ChuyenLCDInfo[dtNLCD.Rows.Count];
                int i = 0;
                foreach (DataRow r in dtNLCD.Rows)
                {
                    chuyenSanXuatInfo.Lcds[i++] = new DTO.ChuyenLCDInfo(r);
                }

            }

            return chuyenSanXuatInfo;
        }

        private void CalcTatkTime(CachedRTU rtu, int count)
        {
            DbUpdateTatkTimeCallback dbTatkTime = new DbUpdateTatkTimeCallback(DbUpdateTatkTime);
            dbTatkTime.BeginInvoke(rtu.com, rtu.idRtu, null, null);
        }

        private int GetNewRTUValue(CachedRTU rtu)
        {
            if (CachecLines.Count > rtu.line && CachecLines[rtu.line - 1] != null)
            {
                return Convert.ToInt32(CachecLines[rtu.line - 1].GetValue(rtu.lenhSX));
            }
            return 0;
        }


        void Send2LCD(CachedRTU rtu)
        {
            string[] val = GetExcelValue(CachecLines[rtu.line - 1]);
            if (val != null)
            {
                val = FilterCached(rtu.line, val);
                foreach (var x in val)
                {
                    SendLCD(rtu.line, x);
                }
            }
        }

        private string[] FilterCached(int line, string[] val)
        {
            if (CachedDataSends.Count >= line)
            {
                if (CachedDataSends[line - 1] == null || CachedDataSends[line - 1].Length != val.Length) CachedDataSends[line - 1] = val;
                else
                {
                    for (var i = 0; i < val.Length; i++)
                    {
                        if (CachedDataSends[line - 1][i] == val[i])
                            val[i] = null;
                        else
                        {
                            CachedDataSends[line - 1][i] = val[i];
                        }
                    }

                }
            }
            else
            {
                while (CachedDataSends.Count < line)
                {
                    CachedDataSends.Add(null);
                }
                CachedDataSends[line - 1] = val;
            }
            return val;
        }

        private string[] GetExcelValue(DTO.ChuyenSanXuatInfo chuyenSanXuatInfo)
        {
            string[] res = null;
            DataSet ds = new DataSet();
            DataTable dt = chuyenSanXuatInfo.ToDataTable();
            dt.Rows.Add(chuyenSanXuatInfo.ToDataRow(dt));
            dt.TableName = "chuyen";
            ds.Tables.Add(dt);
            if (chuyenSanXuatInfo.Lcds != null && chuyenSanXuatInfo.Lcds.Length > 0)
            {
                DataTable dtLCD = chuyenSanXuatInfo.Lcds[0].ToDataTable();
                dtLCD.Rows.Add(chuyenSanXuatInfo.Lcds[0].ToDataRow(dtLCD));
                dtLCD.TableName = "lcd";
                ds.Tables.Add(dtLCD);
            }
            DataTable gl = new DataTable("gl");
            gl.Rows.Add(gl.NewRow());
            DataTable gn = new DataTable("gn");
            gn.Rows.Add(gn.NewRow());
           
            gl.Columns.Add("BatDau");
            gl.Rows[0]["BatDau"] = CachedTimes[chuyenSanXuatInfo.LineId.Value - 1].BatDau;
            gl.Columns.Add("SoGiaiDoan");
            gl.Rows[0]["SoGiaiDoan"] = CachedTimes[chuyenSanXuatInfo.LineId.Value - 1].SoGiaiDoan;
            for (int i = 1; i <= 20; i++)
            {
                gl.Columns.Add("GioLam" + i);
                gl.Rows[0]["GioLam" + i] = DateTime.Today.AddMinutes(Convert.ToInt32(CachedTimes[chuyenSanXuatInfo.LineId.Value - 1].GetValue("GioLam" + i)));
                gn.Columns.Add("GioNghi" + i);
                gn.Rows[0]["GioNghi" + i] = DateTime.Today.AddMinutes(Convert.ToInt32(CachedTimes[chuyenSanXuatInfo.LineId.Value - 1].GetValue("GioNghi" + i)));
            }
            ds.Tables.Add(gl);
            ds.Tables.Add(gn);
            ds.Tables.Add(gtt.Copy());

            string tempPath = Application.StartupPath + "Report";
            string rptPath = Application.StartupPath + "tmp";
            ReportGenerator rg = new ReportGenerator(ds, "LcdExcel", chuyenSanXuatInfo.XuongId, "", tempPath, rptPath);
            ExcelFile xls = rg.CreateReport();
            DataTable dtNChuyen = new DataTable("lcd");

            int total = 0;
            TransferHelper.PreviewExcelFile(dtNChuyen, xls, "", "lcd", ref total);
            res = new string[dtNChuyen.Rows.Count * dtNChuyen.Columns.Count];
            int j = 0;
            foreach (DataRow r in dtNChuyen.Rows)
            {
                foreach (DataColumn c in dtNChuyen.Columns)
                {
                    string tmp = string.Format("{0}", r[c]);
                    if (string.IsNullOrEmpty(tmp)) res[j++] = null;
                    else res[j++] = tmp;
                }
            }
            return res;
        }
        private void Return2RTU(CachedRTU rtu, int newVal)
        {
            if (rtu.idRtu == -1) return;
            SerialPort sport = GetSerialPort(rtu.com);
            if (sport == null) return;
            try
            {
                string disp = "|" + rtu.idRtu.ToString("000") + "|";
                string kq = rtu.idRtu.ToString();
                sport.Parity = Parity.Mark;
                sport.Write(new byte[] { (byte)rtu.idRtu }, 0, 1);
                Sleep(delayCell);
                sport.Parity = Parity.Space;
                kq += 'O'.ToString();
                sport.Write('O'.ToString());
                Sleep(delayCell);
                kq += newVal.ToString();
                sport.Write(newVal.ToString("0000"));
                Sleep(delayCell);
            }
            catch (Exception ex)
            {
                //throw ex;
            }
        }
        private void Sleep(int val)
        {
            Thread.Sleep(val);
        }
        private SerialPort GetSerialPort(int index)
        {
            string portName = gpCOM.Controls[index].Text;
            foreach (MySerialPort p in ports)
            {
                if (portName == p.PortName) return p.Port;
            }
            return null;
        }
        public void DbUpdateSanLuong(int line)
        {
            BUS.ChuyenSanXuatControl bus = new BUS.ChuyenSanXuatControl(_pecController.Bus);
            string sErr = bus.InsertUpdate(CachecLines[line - 1]);
            if (!string.IsNullOrEmpty(sErr)) Log(sErr);
        }
        public void DbUpdateTatkTime(int com, int rtu)
        {
        }
        private void Log(string s)
        {
        }
        public class LCDInfo
        {
            int _soCongDoan = 8;
            int _line = 1;
            string _ip;
            double _tyLeDat;


        }

        public class CachedRTU
        {
            public int com = -1;
            public int line = 0;
            public int idRtu = -1;
            public string lenhSX;
            public int dv = 1;
            public bool reCalculate = false;
        }
        public class CachedLCD
        {
            public string ip;
            public int line;
        }
        public class MyDataPackage
        {
            public int com;
            public string portName;
            public string type;
            public int id;
            public string data;
        }
        public class MySerialPort
        {
            string _portName;
            SerialPort _port;

            public SerialPort Port
            {
                get { return _port; }
                set { _port = value; }
            }

            public string PortName
            {
                get { return _portName; }
                set { _portName = value; }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CachedDataSends = new List<string[]>();
            foreach (var x in CachecLines)
            {
                Send2LCD(new CachedRTU() { line = x.LineId.Value, reCalculate = false });
            }
        }
    }
}
